package com.css.fghs.service.impl;

import cn.hutool.core.util.IdUtil;
import cn.hutool.crypto.Mode;
import cn.hutool.crypto.Padding;
import cn.hutool.crypto.digest.MD5;
import cn.hutool.json.JSONUtil;
import com.css.constant.Result;
import com.css.exception.ServiceException;
import com.css.fghs.entity.domain.FgjyYhzxYhxxbDO;
import com.css.fghs.entity.vo.LoginReqVO;
import com.css.fghs.entity.vo.LoginRespVO;
import com.css.fghs.entity.vo.RegisterReqVO;
import com.css.fghs.service.FgjyYhzxYhxxbService;
import com.css.fghs.service.LoginService;
import com.css.util.GyUtils;
import com.css.util.RedisUtils;
import com.css.util.SM4Utils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;


@Service
@Slf4j
public class LoginServiceImpl implements LoginService {

    @Resource
    private FgjyYhzxYhxxbService yhxxbService;

    @Override
    public void register(RegisterReqVO reqVO) {
//        String base64CipherText = SM4Utils.encode(Mode.ECB, Padding.PKCS5Padding,null,reqVO.getPassword());
//        reqVO.setPassword(base64CipherText);

        FgjyYhzxYhxxbDO yhxxbDONew = new FgjyYhzxYhxxbDO();
        yhxxbDONew.setYhuuid(IdUtil.fastSimpleUUID());
        yhxxbDONew.setYhlx(reqVO.getYhlx());
        yhxxbDONew.setSjhm1(reqVO.getPhone());
        String ymm= SM4Utils.decode(Mode.ECB, Padding.PKCS5Padding,null,reqVO.getPassword());
        final String rawPasswordHex = MD5.create().digestHex(ymm);
        yhxxbDONew.setDlmm(rawPasswordHex);
        yhxxbDONew.setUsername("用户_" + RandomStringUtils.randomAlphanumeric(8));
        yhxxbDONew.setYxbz("Y");
        yhxxbDONew.setRzbz("N");
        yhxxbDONew.setLrrq(new Date());
        yhxxbService.save(yhxxbDONew);
    }

    @Override
    public LoginRespVO login(@Valid LoginReqVO reqVO) throws Exception {
//        String base64CipherText = SM4Utils.encode(Mode.ECB, Padding.PKCS5Padding,null,reqVO.getPassword());
//        reqVO.setPassword(base64CipherText);

        FgjyYhzxYhxxbDO yhxx = yhxxbService.lambdaQuery().eq(FgjyYhzxYhxxbDO::getSjhm1,reqVO.getPhone()).eq(FgjyYhzxYhxxbDO::getYxbz,"Y").eq(FgjyYhzxYhxxbDO::getYhlx,reqVO.getYhlx()).last(" limit 1").one();
        if(GyUtils.isNotNull(yhxx)){
            if (verifyPassword(reqVO.getPassword(),yhxx.getDlmm())){
                Map<String,Object> yhxxMap = new HashMap<>();
                yhxxMap.put("username",yhxx.getUsername());
                yhxxMap.put("yhuuid",yhxx.getYhuuid());
                yhxxMap.put("phone",yhxx.getSjhm1());
                yhxxMap.put("yhlx",yhxx.getYhlx());

                LoginRespVO loginRespVO = new LoginRespVO();
                loginRespVO.setYhuuid(yhxx.getYhuuid());
                loginRespVO.setUsername(yhxx.getUsername());
                loginRespVO.setPhone(yhxx.getSjhm1());
                final String accessToken = IdUtil.fastSimpleUUID();
                loginRespVO.setAccessToken(accessToken);
                Map<String,Object> map = new HashMap<>();
                String jsonStr= JSONUtil.toJsonStr(yhxxMap);
                map.put("yhxx", jsonStr);
                RedisUtils.putHash(accessToken,map);
                RedisUtils.expire(accessToken,2, TimeUnit.HOURS);//过期时间设置2小时
                log.info("登录缓存yhxx:{}",jsonStr);
                return loginRespVO;
            }else {
                throw new ServiceException("登录失败，用户名或密码错误");
            }
        }else {
            throw new ServiceException("登录失败，用户不存在");
        }
    }

    @Override
    public LoginRespVO smsLogin(@Valid RegisterReqVO reqVO) throws Exception {

        FgjyYhzxYhxxbDO yhxx = yhxxbService.lambdaQuery().eq(FgjyYhzxYhxxbDO::getSjhm1,reqVO.getPhone()).eq(FgjyYhzxYhxxbDO::getYxbz,"Y").eq(FgjyYhzxYhxxbDO::getYhlx,reqVO.getYhlx()).last(" limit 1").one();
        if(GyUtils.isNotNull(yhxx)){
            Map<String,Object> yhxxMap = new HashMap<>();
            yhxxMap.put("username",yhxx.getUsername());
            yhxxMap.put("yhuuid",yhxx.getYhuuid());
            yhxxMap.put("phone",yhxx.getSjhm1());
            yhxxMap.put("yhlx",yhxx.getYhlx());
            LoginRespVO loginRespVO = new LoginRespVO();
            loginRespVO.setYhuuid(yhxx.getYhuuid());
            loginRespVO.setUsername(yhxx.getUsername());
            loginRespVO.setPhone(yhxx.getSjhm1());
            final String accessToken = IdUtil.fastSimpleUUID();
            loginRespVO.setAccessToken(accessToken);
            Map<String,Object> map = new HashMap<>();
            String jsonStr= JSONUtil.toJsonStr(yhxxMap);
            map.put("yhxx", jsonStr);
            RedisUtils.putHash(accessToken,map);
            RedisUtils.expire(accessToken,1, TimeUnit.DAYS);//过期时间设置1天
            log.info("登录缓存yhxx:{}",jsonStr);
            return loginRespVO;
        }else {
            throw new ServiceException("登录失败，用户不存在");
        }
    }


    @Override
    public Result resetPassword(@Valid LoginReqVO reqVO) {
//        String base64CipherText = SM4Utils.encode(Mode.ECB, Padding.PKCS5Padding,null,reqVO.getPassword());
//        reqVO.setPassword(base64CipherText);
//        base64CipherText = SM4Utils.encode(Mode.ECB, Padding.PKCS5Padding,null,reqVO.getPassword2());
//        reqVO.setPassword2(base64CipherText);

        FgjyYhzxYhxxbDO yhxx = yhxxbService.lambdaQuery().eq(FgjyYhzxYhxxbDO::getSjhm1,reqVO.getPhone()).eq(FgjyYhzxYhxxbDO::getYxbz,"Y").eq(FgjyYhzxYhxxbDO::getYhlx,reqVO.getYhlx()).last(" limit 1").one();
        if(GyUtils.isNotNull(yhxx)){
//            if(reqVO.getPassword2().equals(yhxx.getDlmm())){
//                throw new ServiceException("修改密码失败，新旧密码不能一致");
//            }
            if(GyUtils.isNull(reqVO.getPassword2())){
                throw new ServiceException("修改密码失败，新密码为空或者无效密码");
            }
            String passWord = MD5.create().digestHex(SM4Utils.decode(Mode.ECB, Padding.PKCS5Padding,null,reqVO.getPassword2()));
            yhxx.setDlmm(passWord);
            yhxx.setXgrq(new Date());
            if(yhxxbService.updateById(yhxx)) return Result.ok(); else return Result.err(-1,"新密码保存失败");
        }else {
            throw new ServiceException("修改密码失败，当前用户无效");
        }
    }

    private boolean verifyPassword(String yhmm, String md5Mm){
        String ymm= SM4Utils.decode(Mode.ECB, Padding.PKCS5Padding,null,yhmm);

        if(GyUtils.isNull(ymm)){
           return false;
        }

        final String rawPasswordHex = MD5.create().digestHex(ymm);
        return rawPasswordHex.equals(md5Mm);
    }


}
